package com.pricl.frame.token.filter;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;

import com.alibaba.fastjson.JSONArray;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.pricl.frame.token.jwt.CertifyConstant;

import net.minidev.json.JSONObject;

/**
 * toekn校验过滤器，所有的API接口请求都要经过该过滤器(除了指定接口)
 *
 */

@WebFilter(urlPatterns="/api/*")
public class Filter1_CheckToken  implements Filter {

	/**
	 * redis
	 */
	@Autowired
	private RedisTemplate redisTemplate;
	
	private static final List<String> WHITE_LIST_REQUEST = Lists.newArrayList();
	
	static {
		WHITE_LIST_REQUEST.add("/api/adminuser/loginCertification"); // 登陆验证
		WHITE_LIST_REQUEST.add("/api/adminuser/savePhoneNumberRegister"); // 电话登陆
		WHITE_LIST_REQUEST.add("/api/adminuser/forgetAuthorization"); // 忘记密码
		WHITE_LIST_REQUEST.add("/api/adminuser/saveThirdPartRegister"); // 第三方登陆
		WHITE_LIST_REQUEST.add("/api/adminuser/getCode"); // 验证码
		WHITE_LIST_REQUEST.add("/api/adminuser/checkCode"); // 验证码校验
		WHITE_LIST_REQUEST.add("/api/adminuser/getAdminUserByPrimaryKey"); // 获取用户非关键信息
		WHITE_LIST_REQUEST.add("/api/adminuser/bindThirdToPhone"); // 绑定第三方到手机
		WHITE_LIST_REQUEST.add("/api/adminuser/regetAccessToken"); // 重新获取token
		WHITE_LIST_REQUEST.add("/api/appversion/info/lastVersion"); // 最新版本
		WHITE_LIST_REQUEST.add("/api/advert/info/advertDetial"); // 广告详情
		WHITE_LIST_REQUEST.add("/api/advert/info/getAdvert"); // 广告列表
		WHITE_LIST_REQUEST.add("/api/adminuser/authorMain"); // 作者
		WHITE_LIST_REQUEST.add("/api/article/info/personalArticle"); // 个人文章
		WHITE_LIST_REQUEST.add("/api/user/comments/praise"); // 点赞
		
		WHITE_LIST_REQUEST.add("/api/common/city");
		WHITE_LIST_REQUEST.add("/api/common/tag");
		WHITE_LIST_REQUEST.add("/api/common/province");
	}

	@Override
	public void doFilter(ServletRequest argo, ServletResponse arg1,
			FilterChain chain ) throws IOException, ServletException {
		HttpServletRequest request=(HttpServletRequest) argo;
		HttpServletResponse response=(HttpServletResponse) arg1;
		request.getHeader("User-Agent");
		// 处理前置空该两参数
		request.setAttribute("id", null);
		request.setAttribute("adminUserId", null);
		
		// 跳过部分请求验证
		if(WHITE_LIST_REQUEST.contains(request.getRequestURI())){
			chain.doFilter(request, response);
			return;
		}
		
		//其他API接口一律校验token
		System.out.println("------------------------开始校验token-----------------------");
		// 获取token
		String access_token = request.getParameter("accessToken");
		if (CertifyConstant.NO_BODY_TOKEN.equals(access_token)) {
			System.out.println("———————————————————————————————————————————————————————该用户为游客，请注意————————————————————");
			request.setAttribute("id", "0");
			request.setAttribute("adminUserId", 0L);
			chain.doFilter(request, response);
			return ;
		}
		// 如果未带参数直接返回
		if (StringUtils.isEmpty(access_token)) {
			// 未带token
			JSONObject outputMSg=new JSONObject();
			outputMSg.put("code", HttpStatus.UNAUTHORIZED.value());
			outputMSg.put("success", false);
			outputMSg.put("msg", "欢迎回来"); // token缺失
			output(outputMSg, response);
		}
		Object redisValue = redisTemplate.opsForValue().get(access_token);
		if (redisValue == null) {
			//token过期或者无效，则输出错误信息返回客户端
			JSONObject outputMSg=new JSONObject();
			outputMSg.put("code", HttpStatus.UNAUTHORIZED.value());
			outputMSg.put("success", false);
			outputMSg.put("msg", "帐号在其他设备登陆，请退出当前帐号或者重新登陆");
			output(outputMSg, response);
		} else {
			Map<String,Serializable> valueMap = JSONArray.parseObject(String.valueOf(redisValue), Map.class);
			// TODO 此处应该校验ip等是否异地
			/*if ( !access_token.equals(redisTemplate.opsForValue().get(valueMap.get("uid")))) {
				// token被挤掉
				JSONObject outputMSg=new JSONObject();
				outputMSg.put("code", HttpStatus.UNAUTHORIZED.value());
				outputMSg.put("success", false);
				outputMSg.put("msg", "帐号在其他设备登陆，请重新登录");
				output(outputMSg, response);
			}*/
			
			request.setAttribute("id", String.valueOf(valueMap.get("uid")));
			request.setAttribute("adminUserId", Long.valueOf(String.valueOf(valueMap.get("adminUserId"))));
			chain.doFilter(request, response);
			return;
		}
		
	}
	
	
	public void output(JSONObject resultJson,HttpServletResponse response) throws IOException{
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/json");
		PrintWriter out = response.getWriter();
		ObjectMapper mapper = new ObjectMapper();  
		out.write(mapper.writeValueAsString(resultJson));
		out.flush();
		out.close();
	}
	
	@Override
	public void init(FilterConfig arg0) throws ServletException {
		SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, arg0.getServletContext());
		System.out.println("token过滤器初始化了");
	}

	@Override
	public void destroy() {
		
	}
	
}
